/**   
 * @Title: StringXML.java 
 * @Package com.esun.network 
 * @Description: (将要发送的数据构建为xml) 
 * @author City Jiangsy@500wan.com   
 * @date 2011-6-1 下午12:26:12  
 * copy right 深圳市易讯天空网络技术有限公司
 */
package com.esun.network;

import java.net.URLEncoder;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import com.esun.util.Base64;
import com.esun.util.RSA;
import com.esun.util.StringUtil;
import com.esun.util.log.EDebug;

/**
 * @ClassName: StringXML
 * @Description: TODO(将要发送的数据构建为xml,并进行RSA&Base64相关处理)
 * @author City Jiangsy@500wan.com
 * @date 2011-6-1 下午12:26:12
 * 
 */
public class StringXML {

	private String strResult; // 其实我想干掉这个字符串的
	PublicKey pK; // 公钥
	PrivateKey prK; // 私钥
	/** 2011-08-03 city 介于中文字符以及全角字符的判定考虑,由于短时间内没有有效解决方案,因此将解析长度减半 */
	private int RSALIMITED = 38; // rsa解析长度限制

	private void setStrResult(String strResult) {
		this.strResult = strResult;
	}

	private String resultNoRSA;

	public StringXML(ArrayList<HashMap<String, String>> dataForBuild) {
		EDebug.o(this, "XMLBuild is <<< START >>>---------------------------------->> ");
		ArrayList<HashMap<String, String>> list = dataForBuild;
		StringBuffer sb = new StringBuffer();
		sb.append("<root>");
		try {
			for (int i = 0; i < list.size(); i++) {

				String keyy = list.get(i).keySet().toString();
				String valuee = list.get(i).values().toString();
				String keyyy = keyy.substring(1, keyy.length() - 1);
				String valueee = valuee.substring(1, valuee.length() - 1);
//				System.out.println(keyyy);
//				System.out.println(valueee);

				// String key = list.get(i).keySet().toString().replace("[",
				// "").replace("]", "");
				sb.append("<" + keyyy + ">");
				sb.append(valueee);
				sb.append("</" + keyyy + ">");
			}
		} catch (Exception e) {
			// TODO: handle exception
			EDebug.o(this, "data error!! build faile!");
		}
		sb.append("</root>");
		resultNoRSA = sb.toString();
		EDebug.o(this, "XML全文# " + resultNoRSA);
	}

	/**
	 * @Title: getListDoRSAAndBase64
	 * @Description: (对构建好的xml文件进行RSA加密以及Base64编码处理)
	 * @param @return params
	 * @return List<NameValuePair> 返回类型
	 * @throws
	 */
	public List<NameValuePair> getListDoRSAAndBase64() {
		// 构建密钥的数据
		String N = "127229136530197319995824967680642139919235321062370946240649169968513580214039961222056295505935057826728768685902472356590118370107335292018409043321909481365388870741185779074098959382117257066188651500217908313018531124891094389984145171642255665597934617509986877167115705425381951138191902941098813458581";
		String D = "75422725839368541116587512692992168973285494584649490095601887520739751665405290651664084970338632095247560801013121649234519260830371903355466526421708414845304904090920045874826602802511974315761510049768490171212567497292613723660488002453436631712083516317761509458552484517117419111964921338576542504129";
		String E = "65537";
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		byte[] byteForRSA;

		try {
			pK = RSA.getPublicKey(N, E);
			prK = RSA.getPrivateKey(N, D);
		} catch (Exception e) {
			EDebug.o(this, "公钥，密钥获取失败");
		}

		if (resultNoRSA.length() < RSALIMITED + 1) {
			EDebug.o(this, "postdata总长少于100");
			byteForRSA = resultNoRSA.getBytes();
			// 对byte[]进行RSA加密
			byteForRSA = RSA.encrypt((RSAPublicKey) pK, byteForRSA);
			EDebug.o(this, "RSA密文# " + StringUtil.bytesToString(byteForRSA));

			// 对RSA密文进行Base64编码
			setStrResult(Base64.base64Encoder(byteForRSA));
			EDebug.o(this, "base64密文# " + strResult);

			// URLEncode我各种纠结的嘞
			params.add(new BasicNameValuePair("msg0", URLEncoder.encode(strResult)));
			params.add(new BasicNameValuePair("countmsg", URLEncoder.encode("1")));

		} else {
			EDebug.o(this, "postdata总长超100");
			params = splitStingForRSA(resultNoRSA, RSALIMITED);
		}
		EDebug.o(this, "---------------------------------->> XMLBuild is >>> END <<< ");
		return params;
	}

	/**
	 * @Title: getListNoRSAButBase64
	 * @Description: (对构建好的xml文件进行Base64编码处理,不进行RSA加密)
	 * @param @return params
	 * @return List<NameValuePair> 返回类型
	 * @throws
	 */
	public List<NameValuePair> getListNoRSAButBase64() {
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		byte[] byteForBase64;
		byteForBase64 = resultNoRSA.getBytes();
		setStrResult(Base64.base64Encoder(byteForBase64));
		EDebug.o(this, "非加密状态base64编码# " + strResult);

		params.add(new BasicNameValuePair("msg0", URLEncoder.encode(strResult)));
		params.add(new BasicNameValuePair("countmsg", URLEncoder.encode("1")));
		EDebug.o(this, "---------------------------------->> XMLBuild is >>> END <<< ");
		return params;

	}

	/**
	 * @Title: splitStingForRSA
	 * @Description: (对超过RSA加密长度限制的String拆分并进行RSA&Base64操作)
	 * @param strData
	 *            String 需要拆分的xml
	 * @param RSALenth
	 *            int 拆分的长度
	 * @param @return list
	 * @return List<NameValuePair> 返回类型
	 * @throws
	 */
	private List<NameValuePair> splitStingForRSA(String strData, int RSALenth) {
		List<NameValuePair> list = new ArrayList<NameValuePair>();
		int countMsg;
		if (strData.length() % RSALenth == 0) {
			countMsg = strData.length() / RSALenth;
		} else {
			countMsg = strData.length() / RSALenth + 1;
		}
		list.add(new BasicNameValuePair("countmsg", URLEncoder.encode(Integer.toString(countMsg))));
		for (int i = 0; i < countMsg; i++) {
			byte[] byteStrData;
			String strItem;
			EDebug.o(this, "第" + Integer.toString(i + 1) + "条msg,总" + Integer.toString(countMsg) + "条");
			if (i != countMsg - 1) {
				strItem = strData.substring(i * RSALenth, ((i + 1) * RSALenth));
				EDebug.o(this, "拆分无加密# " + strItem);
			} else {
				strItem = strData.substring(i * RSALenth, strData.length());
				EDebug.o(this, "拆分无加密# " + strItem);
			}
			byteStrData = strItem.getBytes();
			byteStrData = RSA.encrypt((RSAPublicKey) pK, byteStrData);
			EDebug.o(this, "拆分后RSA密文# " + StringUtil.bytesToString(byteStrData));
			setStrResult(Base64.base64Encoder(byteStrData));
			EDebug.o(this, "拆分后base64密文# " + strResult);
			String msgCount = "msg" + Integer.toString(i);
			list.add(new BasicNameValuePair(msgCount, URLEncoder.encode(strResult)));
			EDebug.o(this, "msgcount=" + msgCount + "|| values=" + strResult);

		}
		return list;
	}
}
